package com.cib.record.service;

import com.jcraft.jsch.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

/**
 * @描述:
 * @Author: zhangh
 * @Time: 2021/5/13 11:31
 **/
@Service
public class UploadService {
    private static final Logger logger = LoggerFactory.getLogger(UploadService.class);

    public static final String SFTP_REQ_HOST = "host";
    public static final String SFTP_REQ_PORT = "port";
    public static final String SFTP_REQ_USERNAME = "username";
    public static final String SFTP_REQ_PASSWORD = "password";
    public static final String SFTP_REQ_PRIVATEKEY = "privateKey";
    Session session = null;
    Channel channel = null;

    @Value("${sftp.req.host}")
    private  String host;
    @Value("${sftp.req.port}")
    private  String port;
    @Value("${sftp.req.username}")
    private  String username;
    @Value("${sftp.req.privateKey}")
    private String privateKey;
    /*@Value("${sftp.req.password}")
    private  String password;*/


    @Value("${target.path}")
    private String target_path;
    //计数器，计算上传失败次数
    private static int count=0;

    public void uploadFile(String audio_path) {
        SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyyMMdd");
        String dateString=simpleDateFormat.format(new Date());

        Map<String,String> sftpDetails=getSftpDeatails();
        try {
            logger.info("进入uploadFile方法");
            UploadService sftpUtil = new UploadService();
            ChannelSftp chSftp = sftpUtil.getChannel(sftpDetails, 60000);
            //在目标服务器存储目录创建一个以日期命名的文件夹
            String targetDir=target_path+dateString;
            try{
                chSftp.ls(targetDir);

            }catch(Exception e){
                chSftp.mkdir(targetDir);
            }
            chSftp.put(audio_path,targetDir,new MyProgressMonitor(), ChannelSftp.RESUME);
            chSftp.quit();
            sftpUtil.closeChannel();



        }catch (Exception e){
            logger.error("upload "+audio_path+" is failed!");
            logger.error(e.getMessage());
            //出现异常线程睡眠一分钟重新上传
            count++;
            if (count>4){
                logger.info("连续5次上传失败，请检查网络状态是否正常");
                System.out.println("count值是"+count);
                return;
            }else{
                try {
                    Thread.sleep(1000*10);
                } catch (InterruptedException interruptedException) {
                    interruptedException.printStackTrace();
                }
                uploadFile(audio_path);
            }


        }


    }



    public ChannelSftp getChannel(Map<String, String> sftpDetails, int timeout) throws JSchException {
        String ftpHost = sftpDetails.get(SFTP_REQ_HOST);
        String port = sftpDetails.get(SFTP_REQ_PORT);
        String ftpUserName = sftpDetails.get(SFTP_REQ_USERNAME);
        String sftprivatekey = sftpDetails.get(SFTP_REQ_PRIVATEKEY);
        //    String ftpPassword = sftpDetails.get(SFTP_REQ_PASSWORD);
        int ftpPort = Integer.valueOf(port);
        JSch jsch = new JSch(); // 创建JSch对象

        //zhangheng:20210615
        //jsch.addIdentity(sftprivatekey);
        session = jsch.getSession(ftpUserName, ftpHost, ftpPort); // 根据用户名，主机ip，端口获取一个Session对象
       /* if (ftpPassword != null) {
            session.setPassword(ftpPassword); // 设置密码
        }*/
        Properties config = new Properties();
        config.put("StrictHostKeyChecking", "no");
        session.setConfig(config); // 为Session对象设置properties
        session.setTimeout(timeout); // 设置timeout时间
        session.connect(5000); // 通过Session建立链接
        channel = session.openChannel("sftp"); // 打开SFTP通道
        channel.connect(); // 建立SFTP通道的连接
        return (ChannelSftp) channel;
    }

    public void closeChannel() throws Exception {
        if (channel != null) {
            channel.disconnect();
        }
        if (session != null) {
            session.disconnect();
        }
    }

    private  Map<String,String>  getSftpDeatails(){
        Map<String, String> sftpDetails = new HashMap<String, String>();
        sftpDetails.put(SFTP_REQ_HOST, host);
        sftpDetails.put(SFTP_REQ_USERNAME, username);
        //sftpDetails.put(SFTP_REQ_PASSWORD, password);
        sftpDetails.put(SFTP_REQ_PORT, port);
        sftpDetails.put(SFTP_REQ_PRIVATEKEY,privateKey);
        return sftpDetails;
    }



    public static class MyProgressMonitor implements SftpProgressMonitor {
        private long count = 0;     //当前接收的总字节数
        private long max = 0;       //最终文件大小
        private long percent = -1;  //进度
        /**
         * 当每次传输了一个数据块后，调用count方法，count方法的参数为这一次传输的数据块大小
         */
        @Override
        public boolean count(long count) {
            this.count += count;
            if (percent >= this.count * 100 / max) {
                return true;
            }
            percent = this.count * 100 / max;
            System.out.println("Completed " + this.count + "(" + percent
                    + "%) out of " + max + ".");
            return true;
        }
        /**
         * 当传输结束时，调用end方法
         */
        @Override
        public void end() {
            System.out.println("Transferring done.");
            //传输结束，比较Md5是否相同
        }
        /**
         * 当文件开始传输时，调用init方法
         */
        @Override
        public void init(int op, String src, String dest, long max) {
            System.out.println("Transferring begin.");
            this.max = max;
            this.count = 0;
            this.percent = -1;
        }
    }
}
